Hér má finna stutt yfirlit yfir helstu föll og pakka í R. Demó-ið er fullt af slettum og málfræðivillum. Það er með vilja gert. Stafsetningavillur eru óviljandi.

Frekari upplýsingar má finna á eftirfarandi slóðum:

1 R-project

Eina sem það gerir er að halda utan um R skjöl og Rmd skjöl í sömu möppu og notar staðsetningu .Rproj

1.1 pakkar

Flestir pakkar eru á cran. Þá er hægt að ná í svona:

# Ég kommenta út fallið svo ég keyri það ekki óvart
# install.packages("here")

2 Notbook og Rmarkdown

Hægt að geyma texta og kóða á sama stað Hægt að blanda saman kóða úr mismunandi forritunarmálum.

3 Þetta er titill

3.1 Þetta undirtitill

… Þannig að það er hægt að gera skýrslu.

  • Lista
  • gera
  • svona
  1. það
  2. er
  3. líka
  4. hægt að gera númeraða lista

Þetta er skáletrað, Þetta er feitletrað og Þetta er bæði.

Hægt er að nota latex stærðfræði notation með því að setja dollara merki fyrir framan og aftan, eins og \(\hat{\beta}=(\mathbf{x}^T\mathbf{x})^{-1}\mathbf{x}^T\mathbf{y}\) :)

Einnig hægt að setja inn chunk svona:

Mathematical displays are marked off with \[ and \], as in \[ e^{i \pi} = -1 \]

Skýrslan er keyrð með ctrl+shift+k

3.2 Kóði

hægt að setja inn kóða “chunk” með því að setja “```” fremst og aftast.

ctr+alt+i gerir það sjálfkrafa

Hægt er að keyra allan chunkinn með ctr+shift+enter eða ýta á ‘play’ takkann sem birtist.

# Þetta er komment. Hægt er að kommenta kóða með því að ýta á ctr+shift+c

5 + 5
## [1] 10

4 Setup

Yfirleitt er fyrsti búturinn setup bútur þar sem við hlöðum inn pökkum sem við ætlum að nota og setjum fram stillingar:

knitr::opts_chunk$set(
    echo = TRUE,                         # Á að prenta kóðan? Hef þetta oft FALSE.
    fig.width = 16 / 2.54,               # Breidd á myndum í tommum, hægt að breyta í hverjum chunk
    fig.asp = 8 / 16,
    message = FALSE,                     # Á að Sýna skilaboð í html skjalinu?
    warning = FALSE,                     # Á að sýna warnings
    include = TRUE,
    dpi = 600,
    dev = "png",
    dev.args=list(bg="white"),
    out.width = "100%"
)

# Fer yfir pakkanna seinna!
library(HMSr)        # Pakkinn okkar
## Warning: replacing previous import 'dplyr::collapse' by 'glue::collapse' when
## loading 'HMSr'
## Warning: replacing previous import 'dplyr::intersect' by 'lubridate::intersect'
## when loading 'HMSr'
## Warning: replacing previous import 'dplyr::union' by 'lubridate::union' when
## loading 'HMSr'
## Warning: replacing previous import 'dplyr::setdiff' by 'lubridate::setdiff' when
## loading 'HMSr'
library(DBI)         # Pakki til að tengjast við gagnagrunninn
## Warning: package 'DBI' was built under R version 3.6.2
library(tidyverse)   # Pakkinn sem breytti því hvernig R er notað
## -- Attaching packages ----------------------------------------------------------------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.0.9000     v purrr   0.3.3     
## v tibble  2.1.3          v dplyr   0.8.3     
## v tidyr   1.0.0          v stringr 1.4.0     
## v readr   1.3.1          v forcats 0.4.0
## -- Conflicts -------------------------------------------------------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(sf)
## Linking to GEOS 3.6.1, GDAL 2.2.3, PROJ 4.9.3
library(seasonal)
## 
## Attaching package: 'seasonal'
## The following object is masked from 'package:tibble':
## 
##     view
library(tsibble)
## 
## Attaching package: 'tsibble'
## The following object is masked from 'package:dplyr':
## 
##     id
library(lubridate)
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:tsibble':
## 
##     interval, new_interval
## The following object is masked from 'package:base':
## 
##     date
library(here)        # Pakki 
## here() starts at C:/Users/Kari.S/Documents/GitHub/HMS_demo
## 
## Attaching package: 'here'
## The following object is masked from 'package:lubridate':
## 
##     here
library(dbplyr)      # Tidyverse fyrir gagnagrunna
## 
## Attaching package: 'dbplyr'
## The following objects are masked from 'package:dplyr':
## 
##     ident, sql
library(ggseas)      # Seasonal adjustment - X13Arima

Sjá helstu skipanir undir help/markdown quick reference

Sjá ýtarlegri samantekt um Rmarkdown:

5 Sækja gögn

5.1 Slóðir

Í windows virkar bara “/” eða “\” en ekki "" því það er escape character.

slod <- "G:/Hagdeild/Manadarskyrsla_Hagdeildar/2019/November/Byggingamarkadur"      # virkar
slod <- "G:\\Hagdeild\\Manadarskyrsla_Hagdeildar\\2019\\November\\Byggingamarkadur" # virkar

Í linux og apple er hins vegar yfirleitt notað "". Því er hægt að nota fallið here úr here pakkanum til þess að notast við slóð sem virkar á öllum stýrikerfum:

slod <- here::here("G", "Hagdeild", "Manadarskyrsla_Hagdeildar", "2019", "November", "Byggingamarkadur")

5.2 Úr grunninum

Hægt er að blanda saman kóða úr mismunandi forritum. Fyrst þarf að búa til tengingu við R.

con <- get_connection_windows()

Svo er hægt að setja inn SQL chunk og vista outputið sem breytu með nafni sem er skilgreint í haus sem “output.var”

SELECT [Dim_Timi_Byggingarar]
      ,[Dim_Timi_Snapshot]
      ,[Dim_Timi_Brunabotamat]
      ,[Dim_Fasteignir]
      ,[Flatarmal]
      ,[Rummal]
      ,[FjoldiHerbergja]
      ,[Brunabotamat]
      ,[Brunabotamat_I]
      ,[VisitalaBrunabotamats]
      ,[Endurstofnverd]
      ,[Endurstofnverd_Afskrifad]
      ,[Husmat]
      ,[Lodarmat]
      ,[Husmat_Fyrirhugad]
      ,[Lodarmat_Fyrirhugad]
  FROM [HgrDwh].[dwh].[Fact_Fasteignir_vw]

Þá er ég kominn með breytuna fasteignir sem ég get notað í R:

fasteignir

5.3 tenging við grunn

dbplyr býður uppá að vinna með SQL gögn eins og þau séu hlutir í R.

visitolur <- tbl(con, dbplyr::in_schema("dwh", "Fact_Visitolur"))
visitolur_dim <- tbl(con, dbplyr::in_schema("dwh", "Dim_Visitolur"))

visitolur %>% 
  left_join(visitolur_dim, by = c("dim_visitolur" = "dim_visitolur_sk")) %>% 
  rename(
    Vísitala = Visitala.y,
    Gildi = Visitala.x
  ) %>% 
  filter(
    Landssvaedi == "Allt Landið"
  ) %>% 
  group_by(Vísitala) %>% 
  summarise(`Fjöldi gilda` = n())

Skipanir eru þýddar yfir í SQL kóða og unnar í R þar til prentað er út. Hægt er að sjá þýðinguna með fallinu show_query.

visitolur %>% 
  left_join(visitolur_dim, by = c("dim_visitolur" = "dim_visitolur_sk")) %>% 
  rename(
    Vísitala = Visitala.y,
    Gildi = Visitala.x
  ) %>% 
  filter(
    Landssvaedi == "Allt Landið"
  ) %>% 
  group_by(Vísitala) %>% 
  summarise(`Fjöldi gilda` = n()) %>% 
  show_query()
## <SQL>
## SELECT "Vísitala", COUNT(*) AS "Fjöldi gilda"
## FROM (SELECT TOP 100 PERCENT "dim_visitolur", "dim_timi", "Landssvaedi", "Visitala.x" AS "Gildi", "Fjolid", "LOAD_DATE", "RECORD_SOURCE", "ETL_ID", "Visitala.y" AS "Vísitala", "VisitalaKodi", "GrunnDags"
## FROM (SELECT "LHS"."dim_visitolur" AS "dim_visitolur", "LHS"."dim_timi" AS "dim_timi", "LHS"."Landssvaedi" AS "Landssvaedi", "LHS"."Visitala" AS "Visitala.x", "LHS"."Fjolid" AS "Fjolid", "LHS"."LOAD_DATE" AS "LOAD_DATE", "LHS"."RECORD_SOURCE" AS "RECORD_SOURCE", "LHS"."ETL_ID" AS "ETL_ID", "RHS"."Visitala" AS "Visitala.y", "RHS"."VisitalaKodi" AS "VisitalaKodi", "RHS"."GrunnDags" AS "GrunnDags"
## FROM dwh.Fact_Visitolur AS "LHS"
## LEFT JOIN dwh.Dim_Visitolur AS "RHS"
## ON ("LHS"."dim_visitolur" = "RHS"."dim_visitolur_sk")
## ) "dbplyr_003") "dbplyr_004"
## WHERE ("Landssvaedi" = 'Allt Landið')
## GROUP BY "Vísitala"

En ef að það á að nota föll sem eru ekki innbyggð í Azure má færa hlutina handvirkt yfir í R með fallinu collect.

visitolur %>% 
  left_join(visitolur_dim, by = c("dim_visitolur" = "dim_visitolur_sk")) %>% 
  rename(
    Vísitala = Visitala.y,
    Gildi = Visitala.x
  ) %>% 
  filter(Landssvaedi == "Allt Landið") %>% 
  collect() %>% 
  mutate(timi = ymd(dim_timi)) %>% 
  ggplot(aes(x = timi, y = Gildi, color = Vísitala)) +
  geom_line()

5.4 csv

Föllin read_csv og read_csv2 eru wrapper föll utan um read_delim.

read_csv2(
  "MAN10001.csv",
  locale = locale(encoding = "WINDOWS-1252")
  )

5.5 excel

readxl::read_excel(
  "Útlán heimila_með veð í húsnæði_verðtr_óverðtr.xlsx",
  sheet = "Raunverð",
  range = "AU2:AX122"
)

6 Meðhöndlun gagna

Þrjár “bragðtegundir”; base R, tidyverse og data.table. Hér er farið yfir tidyverse.

6.1 tsibble

Yfirleitt erum við að vinna með töflur með klassa “data.frame”.

class(mtcars)
## [1] "data.frame"

Tveir stórir gallar við þann hluti af þeim klassa er að þeir prentast mjög kjánalega út (á bara við þegar ekki er verið að vinna í markdown) og ef aðeins er valin einn dálkur breytist hann sjálfkrafa í vector sem hefur aðra eiginleika. Því er hætt við að fá leiðinlegar villur sem erfitt er að finna.

mtcars[ ,1] # allar raðir, fyrsti dálkur
##  [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4
## [16] 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7
## [31] 15.0 21.4
# mtcars[ , 1, drop = FALSE] kemur í veg fyrir umbreytingu, en er auðvelt að gleyma.
mtcars <- as_tibble(mtcars)
class(mtcars)
## [1] "tbl_df"     "tbl"        "data.frame"
mtcars[ ,1]

6.2 magrittr

Pípur eru dálítið umdeildar en geta verið mjög þægilegar!

Í stað þess að skrifa \(f(x, y)\) er hægt að skrifa \(x\text{ %>% }f(y)\).

Sérstaklega hjálplegt því gögnin eru oft fyrsta argument-ið.

Hægt að nota ctrl+shift+M til að setja inn pípu sjálfkrafa

# einhverjar tölur
x <- c(0.109, 0.359, 0.63, 0.996, 0.515, 0.142, 0.017, 0.829, 0.907)

# Hefðbundna leiðin fyrir útreikninga:
round(exp(diff(log(x))), 1)
## [1]  3.3  1.8  1.6  0.5  0.3  0.1 48.8  1.1
# Með endurteknu assignment er það læsilegra

x2 <- log(x)
x2 <- diff(x2)
x2 <- exp(x2)
x2 <- round(x2, 1)
# Með pípu er það þægilegra:
x %>% 
  log() %>%
  diff() %>%
  exp() %>%
  round(1)
## [1]  3.3  1.8  1.6  0.5  0.3  0.1 48.8  1.1

6.3 tidyr

Hugmyndin á bakvið tidyverse pakkanna er að öll gögn, bæði intak og úttak, séu tidy, sem þýðir í raun aðeins að hver dálkur hefur eina, og aðeins eina breytu (Þótt að hvað teljist breyta getur verið óljóst og farið aðeins eftir samhengi). Annars staðar er þetta kallað long formatt. Í raun sama formatt á gögnunum eins og excel krefst til þess að hægt sé að nota pivot-töflur með góðu móti.

Sjá meira um tidy gögn hér

Þetta form er þægilegt fyrir gagnavinnslu en óþægilegt til þess að lesa úr og þess vegna er gott að geta farið á milli!

Tidyr pakkinn inniheldur nokkur föll sem hjálpa að ymbreyta untidy gögnum í tidy gögn. Það er líklega lítil þörf á honum þegar notast er við gögn úr grunninum en getur verið mjög hjálplegur við önnur gögn, t.d. úr excel.

6.3.1 gather (pivot_longer)

Fölling gather og pivot_longer eru bæði til þess fallin að fara úr wide formatti yfir í long. Gather er fljótlegra en pivot_longer er sveigjanlegra og sumum finnst það læsilegra.

Hérna er gagnasett frá hagstofunni þar sem hluti af dálkheitum, þ.e. landssvæði, eru í raun breytur.

pop <- read_csv(
  "https://px.hagstofa.is:443/pxis/sq/16fe80b6-c886-4d5d-b2e4-17240fd28f2f", 
  locale = locale(
    encoding = "WINDOWS-1252",
    decimal_mark = ",", 
    grouping_mark = "."
  )
)

pop

Hér er hægt að nota gather fallið til þess að safna saman dálkum. Fyrsta argumentið (fyrir utan gögnin sem eru fyrir framan í pípunni) er nafnið sem dálkurinn fær sem geymir nöfnin þá þeim dálkum sem er safnað saman. Annað argumentið erð nafn á dálkinum sem geymir gögnin. Svo koma nöfn á dálkunum sem á að safna saman. Hér má nota ýmiss hjálparföll sem verður vikið að síðar.

pop_tidy <- pop %>% 
  gather(
    key = "Landssvæði",
    value = "Fólksfjöldi",
    Höfuðborgarsvæði:`Suðurland` # Tilgreina hvaða dálkum á að safna saman
  )

pop_tidy
# Athugið, vildi ekki taka "Alls" með!

Önnur leið, oft fljótlegri er að tilgreina hvaða breytur á ekki að safna saman:

pop %>% 
  gather(
    key = "Landssvæði",
    value = "Fólksfjöldi",
    - Aldur,
    - Ár,
    - Kyn,
    - Alls
  )
pop %>% 
  pivot_longer(
    cols = Höfuðborgarsvæði:`Suðurland`, 
    names_to = "Landssvæði",
    values_to = "Fólksfjöldi"
  )

6.3.2 spread og pivot_wider

Föllin spread og pivot_wider eru andhverfur við gather og pivot_longer. Mun sjaldnar notað, en oft gott áður en gögn eru skrifuð út í csv eða excel skjal ef að helsti tilgangur þeirra er að skoða þau en ekki vinna áfram með þau.

pop_tidy %>% 
  select(-Alls) %>% # Tók út "Alls" til þess að fá Karla og Konur í sömu röðum. 
  spread(Kyn, Fólksfjöldi)
pop_tidy %>% 
  select(-Alls) %>% 
  pivot_wider(
    names_from = Kyn,
    values_from = Fólksfjöldi
  )

Sjá flóknari notkun hér.

6.3.3 SQL eftirhermur

Hægt er að tengja saman gögn úr mismunandi df með föllunum left_join, right_join, inner_join, og full_join. Ef að töflurnar hafa sömu nöfn og sama classa (t.d. factor, charachter, logical, int eða double).

Föllinn semi_join má nota til þess að sjá hvaða raðir verða “join-aðar” og anti_join má nota til þess að sjá hvaða raðir verða ekki “join-aðar”.

Ef töflurnar hafa sömu dálkaheiti má sameina þær með bind_rows (fara varlega!) og ef þær eru með jafnmörgum röðum má nota bind_columns.

Mengja virkjarnir intersect, setdiff og union má beita á raðir ef að dálkar eru þeir sömu.

6.3.4 Önnur hjálpleg föll

  • seperate Til þess að splitta einum dálki í tvo eða fleiri dálka
  • extract Sama og seperate nema hendir öllum dálkum nema fyrsta
  • unite Sameinar tvo eða fleiri dálka í einn
  • complete Bætir við röðum sem vantar; breytir implicit NA í explicit NA
  • fill fyllir uppí NA miðað við gildin á undan eða eftir (Getur verið algjörlega nauðsynlegt að nota með group_by til þess að ekki séu notuð óviðeigandi gildi - sjá síðar)
  • drop_na henda út röðum með NA gildi í ákveðnum dálkum (eða einhverjum dálkum)
  • replace_na Sá sem giskar rétt á þetta fær ís að launum.

6.4 dplyr

Samansafn af fimm sögnum, ásamt hjálparföllum, sem auðvelda alla meðhöndlun gagna.

  • mutate
  • select
  • filter
  • summarize
  • arrange

dplyr pakkinn inniheldur einnig group_by fallið sem gerir það að verkum að aðrar aðgerðir séu skipt í hópa eftir gildum á viðkomandi breytum. Sést betur með notkun.

pop_tidy %>% 
  group_by(Landssvæði) %>% 
  class
## [1] "grouped_df" "tbl_df"     "tbl"        "data.frame"

mutate fallið er notað til þess að framkvæma útreikninga á dálkum. Athugið, að ólíkt base-R er ekki gert ráð fyrir gæsalöppum á dálkheitum. Það getur gert lífið aðeins flóknara þegar verið er að búa til föll, en það er dýflisa sem má bíða betri tíma! (hint: litlum sálum ráðlagt að googla ekki ‘rlang’ rétt fyrir svefninn).

pop_tidy %>% 
  group_by(Landssvæði, Kyn) %>% # Hér er mikilvægt að hópa bæði eftir kyni og Landssvæði, annars væri niðurstaðan della!
  mutate(
    Fjölgun = Fólksfjöldi / lag(Fólksfjöldi) - 1,
    Hlutfall = Fólksfjöldi / Alls,
    `Hlutfallsleg fjölgun` = Fjölgun / Fólksfjöldi # Get nýtt það sem er reiknað að ofan innan sama falls! 
  )

mutate virkar aðeins ef að úttakið er jafn stórt og fjöldi raða!

select fallið er nýtt til þess að velja dálka

pop_tidy %>% 
  select(Fólksfjöldi) # Frekar gagnslaust í þessu samhengi

Einnig hægt að nota til þess að henda út dálkum:

pop_tidy %>% 
  select(-Alls)

filter er notað til þess að velja raðir út frá skilyrðum:

pop_tidy %>% 
  group_by(Landssvæði, Kyn) %>% # Hér er mikilvægt að hópa bæði eftir kyni og Landssvæði, annars væri niðurstaðan della!
  mutate(
    Fjölgun = Fólksfjöldi / lag(Fólksfjöldi) - 1,
    Hlutfall = Fólksfjöldi / Alls,
    `Hlutfallsleg fjölgun` = Fjölgun / Fólksfjöldi # Get nýtt það sem er reiknað að ofan innan sama falls! 
  ) %>% 
  filter(
    !is.na(Fjölgun),
    Kyn == "Karlar"
  )

Athugið að föll inní mutate ná utan um allan dálkin í viðkomkandi hóp eins og hann er skilgreindur miðað við group_by á meðan nafn á dálki vísar aðeins til viðkomandi raðar. Því má t.a.m. fá hlutfallslega skiptingu karla og kvenna með eftirfarandi hætti:

pop_tidy %>% 
  group_by(Ár, Landssvæði) %>% 
  mutate(
    # Hér nær fyrra 'Fólksfjöldi' breytan til einnar raðar, en sú seinni til tveggja!
    Hlutfall = Fólksfjöldi / sum(Fólksfjöldi)
  )

summarize er svipað og mutate, en þar er fjöldi raða jafn margar og fjöldi hópa:

pop_tidy %>% 
  filter(Ár == max(Ár)) %>% 
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  )

Sum föll virka bæði í summarize og mutate:

pop_tidy %>% 
  filter(Ár == max(Ár)) %>% 
  group_by(Ár, Landssvæði) %>% 
  mutate(
    Alls = sum(Fólksfjöldi),
    n = n() # n() er hjálparfall sem sýnir fjölda raða!
  )

count sýnir fjölda raða eftir tilgreindum breytum, en group_by breytum er alltaf bætt við!

pop_tidy %>% 
  count(Ár, Kyn)
pop_tidy %>% 
  group_by(Kyn) %>% 
  count(Ár)

tally er svipað en ekki er farið yfir það hér.

6.5 lubridate

Lubridate pakkinn er aðalega notaður til þess að vinna með dagsetningar í R. Þegar gögn eru sótt í gegnum SQL inní R koma dagsetningar sem strengir.

fasteignir %>% 
  mutate(
    Dim_Timi_Utgefid = Dim_Timi_Byggingarar %>% ymd(),
    Dim_Timi_Thinglyst = Dim_Timi_Snapshot  %>% ymd(),
    Dim_Timi_Brunabotamat = Dim_Timi_Brunabotamat %>% ymd()
  )

Lubridate pakkinn virkar meira að segja nokkuð vel með íslenska staðla:

vnv <- read_hagstofan("https://px.hagstofa.is:443/pxis/sq/7fa32768-b4c5-4499-a869-5b57c079d90a", delim = "\t")

vnv
vnv %>% 
  mutate(
    time = ymd(paste(Ár, Mánuður, 01))
  )

Þá inniheldur lubridate pakkinn ýmiss föll sem auðvelda lífið þegar kemur að því að gera útreikninga sem innihalda tíma.

7 Gröf - ggplot

7.1 Grunneiningin

Til eru ýmsar leiðir til þess að gera gröf í R. Hér munum við einbeita okkur af einum pakka, ggplot2, sem byggir á grammar of graphics hugmyndafræðinni. Hér er í raun hægt að fara mjög djúpt, en aðeins verður tæpt á helstu þáttunum.

ggplot fallið er fall sem býr til hlut af classa gg og má hugsa sem nánast tóma uppskrift af grafi.

p <- pop_tidy %>% 
  ggplot()

str(p)
## List of 9
##  $ data       :Classes 'tbl_df', 'tbl' and 'data.frame': 352 obs. of  6 variables:
##   ..$ Aldur      : chr [1:352] "Alls" "Alls" "Alls" "Alls" ...
##   ..$ Ár         : num [1:352] 1998 1998 1999 1999 2000 ...
##   ..$ Kyn        : chr [1:352] "Karlar" "Konur" "Karlar" "Konur" ...
##   ..$ Alls       : num [1:352] 136444 135937 138086 137626 139665 ...
##   ..$ Landssvæði : chr [1:352] "Höfuðborgarsvæði" "Höfuðborgarsvæði" "Höfuðborgarsvæði" "Höfuðborgarsvæði" ...
##   ..$ Fólksfjöldi: num [1:352] 81077 83529 82976 85368 84653 ...
##  $ layers     : list()
##  $ scales     :Classes 'ScalesList', 'ggproto', 'gg' <ggproto object: Class ScalesList, gg>
##     add: function
##     clone: function
##     find: function
##     get_scales: function
##     has_scale: function
##     input: function
##     n: function
##     non_position_scales: function
##     scales: NULL
##     super:  <ggproto object: Class ScalesList, gg> 
##  $ mapping    : Named list()
##   ..- attr(*, "class")= chr "uneval"
##  $ theme      : list()
##  $ coordinates:Classes 'CoordCartesian', 'Coord', 'ggproto', 'gg' <ggproto object: Class CoordCartesian, Coord, gg>
##     aspect: function
##     backtransform_range: function
##     clip: on
##     default: TRUE
##     distance: function
##     expand: TRUE
##     is_free: function
##     is_linear: function
##     labels: function
##     limits: list
##     modify_scales: function
##     range: function
##     render_axis_h: function
##     render_axis_v: function
##     render_bg: function
##     render_fg: function
##     setup_data: function
##     setup_layout: function
##     setup_panel_guides: function
##     setup_panel_params: function
##     setup_params: function
##     train_panel_guides: function
##     transform: function
##     super:  <ggproto object: Class CoordCartesian, Coord, gg> 
##  $ facet      :Classes 'FacetNull', 'Facet', 'ggproto', 'gg' <ggproto object: Class FacetNull, Facet, gg>
##     compute_layout: function
##     draw_back: function
##     draw_front: function
##     draw_labels: function
##     draw_panels: function
##     finish_data: function
##     init_scales: function
##     map_data: function
##     params: list
##     setup_data: function
##     setup_params: function
##     shrink: TRUE
##     train_scales: function
##     vars: function
##     super:  <ggproto object: Class FacetNull, Facet, gg> 
##  $ plot_env   :<environment: 0x000000001ff44c88> 
##  $ labels     : Named list()
##  - attr(*, "class")= chr [1:2] "gg" "ggplot"

Við uppskriftina er hægt að bæta ýmsum liðum sem stjórna því hvað er á grafinu. Í lokinn er hægt að prenta það út með ýsmum hætti. Ef plottinu er ekki asign-að prentast það sjálfkrafa út í console.

Inni upphaflega fallið er yfirleitt skilgreint hvaða litið grafsins stjórnast af hvaða breytu. Það er tekið fram í aes fallinu, sem stendur fyrir aestetics, og output-ið úr því er vísað á argument-ið mapping. Þættir eiga ekki að stjórnast af gögnum heldur eru alltaf þeir sömu má skilgreina fyrir utan aes fallið.

Athugið að nú prentast aðeins tómt graf því ekki er búið að taka fram hvaða geometry á að vera á grafinu.

pop_tidy %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, fill = Landssvæði), color = "pink")

7.2 geom

Bæta má öðrum liðum við plottið með því + virkjanum. Það fyrsta sem er yfirleitt bætt við er geometry sem stjórnar því hvort að gögnin séu plottuð sem súlurit, línurit eða eitthvað annað. Öll föllin bera heiti sem byrja á geom_ og svo er nafninu á viðkomandi geom bætt við. Hér hefur verið bætt við column.

pop_tidy %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, fill = Landssvæði)) +
  geom_col()

Einnig er hægt að setja mappings í geom föllunum, en það er yfirleitt aðeins gert ef að það á að vera mismunandi eftir geom. Í geom fallinu má einnig bæta við parametrum sem að eiga að vera óbreytt milli mælinga.

pop_tidy %>% 
  ggplot() +
  geom_col(aes(x = Ár, y = Fólksfjöldi, fill = Landssvæði), color = "pink")

Sjálfgefið val er staflað súlurit, en auðvelt er að breyta því með position argumentinu.

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  ggplot(aes(x = Ár, y = Fólksfjöldi, fill = Landssvæði)) +
  geom_col(position = position_dodge())

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  ggplot(aes(x = Ár, y = Fólksfjöldi, fill = Landssvæði)) +
  geom_col(position = position_fill())

Auðvelt er að breyta yfir í breyta um tegund af plotti með því að breyta um geom

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line()

Línuritiði hér að ofan er mjög skrítið, því að það eru í raun tvær tölur í gögnunum fyrir hvert ár og hvert landssvæði, eitt fyrir hvort kynið. Í geom_col er það sjálfkrafa lagt saman, en ekki í geom_line. Einn möguleiki er að summera fyrirfram.

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line()

Þá er einnig hægt að hafa fleira en eitt geom. Hér er t.d bæði notað line og point:

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line() +
  geom_point()

7.3 Theme og titlar

Auðvelt er að bæta við titli, undirtitli og caption eða að breyta nöfnum á ásum:

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line() +
  geom_point() +
  labs(
    title = "Þetta er titill",
    subtitle = "Þetta er undirtitill",
    caption = "Þetta er caption",
    x = NULL,
    y = "Þetta er ekki lýsandi nafn á ás"
  )

Þemu stjórna heildarútliti á gröfum, svo sem litum á bakgrunni, leturgerð, lóðréttum og láréttum línum og svo lengi mætti telja. Sjá heildarlista í ?theme.

Búið er að útbúa nýtt theme fyrir HMS en það má finna á github undir á (github/karsfri/ILS)[“https://github.com/karsfri/ILS/raw/master/theme_hms.R”]. Því má bæta við með með sambærilegum hætti, þ.e. bæta við línunni + theme_ils() við kóðann:

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line() +
  geom_point() +
  theme_hms() +
  labs(
    title = "Þetta er titill",
    subtitle = "Þetta er undirtitill",
    caption = "Þetta er caption",
    x = NULL, # Ef það á að sleppa label
    y = "Þetta er ekki lýsandi nafn á ás"
  )

Þótt að theme_hms virkar áægætlega í flestum tilfellum er stundum þörf til þess að bregða útaf. Þá er ekkert mál að bæta við öðru theme falli við plottið:

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line() +
  geom_point() +
  theme_hms() +
  theme(
    axis.text.x = element_text(angle = 90, color = "pink", face = "bold")
  ) +
  labs(
    title = "Þetta er titill",
    subtitle = "Þetta er undirtitill",
    caption = "Þetta er caption",
    x = NULL, # Ef það á að sleppa label
    y = "Þetta er ekki lýsandi nafn á ás"
  )

Athugið að theme fallið þarf að koma eftir theme_hms.

Athugið að inní hms pakkanum er theme_vertical_x sem að setur labels á x-ás í 90° og lagar justification.

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line() +
  geom_point() +
  theme_hms() +
  theme_vertical_x +
  labs(
    title = "Þetta er titill",
    subtitle = "Þetta er undirtitill",
    caption = "Þetta er caption",
    x = NULL, # Ef það á að sleppa label
    y = "Þetta er ekki lýsandi nafn á ás"
  )

7.4 Skalar

Á meðan aes stjórnar hvaða breytur breyta mismunandi aspectum plotsins, þá stjórna scale_ föllin því hvernig. Þau stjórna því hvernig ásar breytast, og hvaða litir eru notaðir.

7.4.1 Litir

Gott er að nota palette_hms fyrir “stór” geom, svo sem svæðisrit og súlurit og palette_hms_dark fyrir “lítil” geom, svo sem punkta og línur.

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line() +
  geom_point() +
  theme_hms() +
  theme(
    axis.text.x = element_text(angle = 90, color = "pink", face = "bold")
  ) +
  labs(
    title = "Þetta er titill",
    subtitle = "Þetta er undirtitill",
    caption = "Þetta er caption",
    x = NULL, # Ef það á að sleppa label
    y = "Þetta er ekki lýsandi nafn á ás"
  ) +
  scale_color_manual(values = palette_hms_darker)

Með því að nota fallið theme_set_hms má yfirskrifa default thema og litaskema þannig að yfirleitt þarf ekki að taka það fram ef þetta fall er notað í byrjun. Athugið samt að það hefur hliðarverkanir.

theme_set_hms()
pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line() +
  geom_point() +
  labs(
    title = "Þetta er titill",
    subtitle = "Þetta er undirtitill",
    caption = "Þetta er caption",
    x = NULL, # Ef það á að sleppa label
    y = "Þetta er ekki lýsandi nafn á ás"
  ) 

Liturinn #ff5028 hefur verið valinn sem áherslulitur, og hefur verið assign-aður undir red.

pop_tidy %>% 
  filter(
    Ár == 2018,
    Kyn == "Karlar"
    ) %>% 
  mutate(
    hbs = if_else(Landssvæði == "Höfuðborgarsvæði", "Illmenni", "Góðmenni")
  ) %>% 
  ggplot(aes(Landssvæði, Fólksfjöldi, fill = hbs)) +
  geom_col() +
  scale_fill_manual(values = c(palette_hms[1], red))

7.4.2 Ásar

Breyta má ásum með föllunum sem byrja á scale_y_[type] eða scale_x_[type].

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line() +
  geom_point() +
  labs(
    title = "Þetta er titill",
    subtitle = "Þetta er undirtitill",
    caption = "Þetta er caption",
    x = NULL, # Ef það á að sleppa label
    y = "Þetta er ekki lýsandi nafn á ás"
  ) +
  scale_y_continuous(
    breaks = seq(0, 5*10^5, by = 2.5*10^4), # Setja línubil í 25.000,
    limits = c(0, 3 * 10 ^ 5), # Bilið á ásnum. Hægt að setja NA ef aðeins á að stjórna efri eða neðri mörkum,
    labels = scales::label_comma(big.mark = ".", decimal.mark = ",") # sjá einnig accuracy og scale!
  ) 

Vegna þess að kommur og punktar eru með öðrum hætti en í USA má nota föllin label_isl, label_isk og label_percent úr hms pakkanum.

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line() +
  geom_point() +
  labs(
    title = "Þetta er titill",
    subtitle = "Þetta er undirtitill",
    caption = "Þetta er caption",
    x = NULL, # Ef það á að sleppa label
    y = "Þetta er ekki lýsandi nafn á ás"
  ) +
  scale_y_continuous(
    breaks = seq(0, 5*10^5, by = 2.5*10^4), # Setja línubil í 25.000,
    limits = c(0, 3 * 10 ^ 5), # Bilið á ásnum. Hægt að setja NA ef aðeins á að stjórna efri eða neðri mörkum,
    labels = label_isl() # fall úr hms pakkanum.
  )

7.4.3 Annað

7.5 Facets

Samanburður getur stundum verið óskýr eða jafnvel villandi ef að margar línur eru á sama grafi. Þá getur oft verið gott að nota facets. Fallið facet_wrap er hugsað til þess að nota fyrir eina breytu á meðan facet_grid er hugsað fyrir eina eða tvær þar sem hver breyta er ekki í fleiri en einni röð eða einum dálki.

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line() +
  geom_point() +
  labs(
    title = "Þetta er titill",
    subtitle = "Þetta er undirtitill",
    caption = "Þetta er caption",
    x = NULL, # Ef það á að sleppa label
    y = "Þetta er ekki lýsandi nafn á ás"
  ) +
  scale_y_continuous(
    breaks = seq(0, 5*10^5, by = 2.5*10^4), # Setja línubil í 25.000,
    limits = c(0, 3 * 10 ^ 5), # Bilið á ásnum. Hægt að setja NA ef aðeins á að stjórna efri eða neðri mörkum,
    labels = label_isl() # fall úr hms pakkanum.
  ) +
  facet_wrap(~Landssvæði)

Ef að ásarnir mega vera vera misjafnir má notast við scales argumentið. Athugið að þá verð ég samt að taka út efri mörkin limits í scale_y_continous:

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line() +
  geom_point() +
  labs(
    title = "Þetta er titill",
    subtitle = "Þetta er undirtitill",
    caption = "Þetta er caption",
    x = NULL, # Ef það á að sleppa label
    y = "Þetta er ekki lýsandi nafn á ás"
  ) +
  scale_y_continuous(
    # breaks = seq(0, 5*10^5, by = 2.5*10^4), # Setja línubil í 25.000,
    limits = c(0, NA), # Bilið á ásnum. Hægt að setja NA ef aðeins á að stjórna efri eða neðri mörkum,
    labels = label_isl() # fall úr hms pakkanum.
  ) +
  facet_wrap(~Landssvæði, scales = "free_y")

7.6 Coords

Coord er stytting á Coordinate system. Það hefur áhrif á umbreytingu sem á sér stað eftir útreikningum á gögnum:

  • coord_cartesian er sjálfvalið, en hægt að kalla í fallið t.d. ef að það á að takmarka ásana
  • coord_flip víxlar x-ás og y-ás.
  • coord_polar umbreytir yfir í pólarhnit. Má t.d. nota til þess að umbreyta súluriti yfir í skífurit.
pop_tidy %>% 
  filter(
    # Landssvæði == "Höfuðborgarsvæði",
    Ár %in% c(1998, 2008, 2018)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, fill = Landssvæði)) +
  geom_col(position = position_fill(), width = 9) +
  coord_polar(theta = "y", start = 0)

7.7 Annotations

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line() +
  geom_point() +
  theme_hms() +
  labs(
    title = "Þetta er titill",
    subtitle = "Þetta er undirtitill",
    caption = "Þetta er caption"
  )

pop_tidy %>% 
  filter(Ár >= 2013) %>% # Svo að myndin verði ekki of crowded
  group_by(Ár, Landssvæði) %>% 
  summarise(
    Fólksfjöldi = sum(Fólksfjöldi)
  ) %>% 
  ggplot(aes(x = Ár, y = Fólksfjöldi, color = Landssvæði)) +
  geom_line() +
  geom_point() +
  theme_hms() +
  labs(
    title = "Þetta er titill", #%>% toupper(),
    subtitle = "Þetta er undirtitill",
    caption = "Þetta er caption"
  ) +
  scale_color_manual(values = palette_hms_darker)

7.8 Vista myndir

ggsave_both("prufa")

7.9 forcats

7.10 Seasonal decomposition

kaupsamningar <- tbl(con, dbplyr::in_schema("dwh", "Fact_Kaupsamningar_Stakar"))
Dim_Fasteignir <- tbl(con, dbplyr::in_schema("dwh", "Dim_Fasteignir"))

kaupsamningar <-
  kaupsamningar %>% 
  left_join(Dim_Fasteignir %>% select(-LOAD_DATE, -RECORD_SOURCE, -ETL_ID), by = c("Dim_Fasteignir" = "Dim_Fasteignir_sk")) %>%   sql_clean() %>% 
  mutate_if(is.Date, "floor_date", "month") %>% 
  group_by(Landshluti, Dim_Timi_Utgefid) %>% 
  summarise(fjoldi = n()) %>% 
  filter(
    year(Dim_Timi_Utgefid) >= 2009,
    Landshluti != "Vantar"
  ) %>% 
  
  ungroup() %>% 
  # filter(Landshluti == "Höfuðborgarsvæði") %>% 
  mutate(Landshluti = as.factor(Landshluti)) 

Árstíðarleiðrétt sería

kaupsamningar %>% 
  filter(Landshluti == "Höfuðborgarsvæði") %>% 
  ggsdc(aes(Dim_Timi_Utgefid, y = fjoldi), method = "seas", frequency = 12, start = 2009) +
  geom_line() 

Árstíðarleiðrétting í plotti:

kaupsamningar %>% 
  ggplot(aes(Dim_Timi_Utgefid, y = fjoldi, color = Landshluti)) +
  geom_line() + 
  stat_seas(frequency = 12, start = 2009, color = "black", alpha = 0.6) +
  facet_wrap(~Landshluti, scales = "free_y")

Fallið stat_rollapplyr má nota til þess að gera rolling summary:

kaupsamningar %>%
  ggplot(aes(Dim_Timi_Utgefid, y = fjoldi, color = Landshluti)) +
  stat_rollapplyr(width = 12, align = "right", fun = mean) +
  geom_line() +
  facet_wrap(~Landshluti, scales = "free_y")

Þessi föll kalla öll á seas fallið úr seasonal pakkanum til þess að framkvæma “X-13 arima” árstíðarleiðréttingu. Fallið map_seas er heimatilbúið fall sem að virkar innan tidyverse heimsins.

kaupsamningar %>%
  group_by(Landshluti) %>%
  map_seas(fjoldi, Dim_Timi_Utgefid)

8 Föll

Hefðbundið fall:

fun1 <- function(x){
  x + 2
}

tibble(
  x = 1:10
) %>% 
  mutate(y = fun1(x))

Ef að pípa byrjar á “.” þá er því breytt í fall

fun2 <- . %>% exp()

tibble(
  x = 1:10
) %>% 
  mutate(y = fun2(x))

“Wrapper” föll geta eru föll eru notuð til þess að breyta default argumentum á föllum sem þegar eru til. Þá getur verið gott að nota “…” (ellipsis) notation sem heldur utan um öll argument sem ekki eru skilgreind beint í viðkomandi falli. Gott dæmi er ggsave_png fallið sem er staðlar nokkur helstu argument fyrir HMS.

ggsave_png <- function(filename, plot = last_plot(), device = ragg::agg_png, width = width_wide,
                       height = height_regular, units = "cm", dpi = dpi_reg, bg = "white", ...){
  ggsave(filename = filename, plot = plot, device = device, width = width, height = height, units = units,
         res = dpi, background = bg, ...)
}